import logging
import os
import time
import inspect
import traceback

root_path = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
log_path = os.path.join(root_path, 'log')

if not os.path.exists(log_path):
    os.makedirs(log_path)


# 自定义格式化器，根据消息内容判断是否需要完整格式
class CustomFormatter(logging.Formatter):
    def format(self, record):
        if not record.msg:  # 如果消息为空，则使用简化的格式
            self._style._fmt = '%(message)s'  # 只显示消息本身
        else:
            self._style._fmt = '[%(asctime)s][%(filename)s %(lineno)d][%(levelname)s]: %(message)s'  # 完整格式
        return super().format(record)


class CustomLogger:
    def __init__(self):
        # 定义日志位置和文件名
        self.logname = os.path.join(log_path, "{}.log".format(time.strftime("%Y-%m-%d_%H%M%S")))

        # 主日志器
        self.logger = logging.getLogger("log")
        self.logger.setLevel(logging.DEBUG)

        # 创建常规日志格式
        self.formatter = CustomFormatter()  # 使用自定义格式化器

        # 文件日志处理器
        self.filelogger = logging.FileHandler(self.logname, mode='a', encoding="UTF-8")
        self.filelogger.setLevel(logging.DEBUG)
        self.filelogger.setFormatter(self.formatter)

        # 控制台日志处理器
        self.console = logging.StreamHandler()
        self.console.setLevel(logging.DEBUG)
        self.console.setFormatter(self.formatter)

        # 将处理器添加到日志器
        self.logger.addHandler(self.filelogger)
        self.logger.addHandler(self.console)

    # 直接暴露日志记录方法
    def info(self, msg):
        self._log(logging.INFO, msg)

    def debug(self, msg):
        self._log(logging.DEBUG, msg)

    def warning(self, msg):
        self._log(logging.WARNING, msg)

    def error(self, msg, exc_info=False):
        if exc_info:
            msg += "\n" + traceback.format_exc()  # 手动添加 traceback 信息
        self._log(logging.ERROR, msg)

    def critical(self, msg):
        self._log(logging.CRITICAL, msg)

    def _log(self, level, msg):
        # 获取调用日志方法的堆栈帧
        callerframerecord = inspect.stack()[2]
        frame = callerframerecord[0]
        info = inspect.getframeinfo(frame)

        # 创建 LogRecord 对象并设置实际代码行数
        record = self.logger.makeRecord(self.logger.name, level, info.filename, info.lineno, msg, None, None,
                                        info.function)
        self.logger.handle(record)


# 初始化日志器
logger = CustomLogger()
